/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.demo.scheduler.service.task.base;

import info.peigen.hotpot.demo.scheduler.domain.Task;
import info.peigen.hotpot.demo.scheduler.service.enums.TaskStatus;
import info.peigen.hotpot.demo.scheduler.service.step.base.AbstractStepProcessor;
import info.peigen.hotpot.demo.scheduler.service.step.base.TaskContext;
import info.peigen.hotpot.demo.scheduler.service.step.base.TaskProcessor;
import info.peigen.hotpot.demo.scheduler.service.step.processor.robot.*;
import info.peigen.hotpot.demo.scheduler.service.step.processor.stub.StubArmLeftProcessor;
import info.peigen.hotpot.demo.scheduler.service.step.processor.stub.StubArmUpProcessor;
import info.peigen.hotpot.demo.scheduler.service.step.processor.stub.StubCableOutProcessor;
import info.peigen.hotpot.demo.scheduler.service.step.processor.stub.StubWakeUpProcessor;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.EventBus;

import java.util.List;

/**
 * <b>(AbstractTaskProcessor)</b>
 *
 * @author Lihai
 * @version 1.0.0
 * @since 2023/9/9
 */
@FieldDefaults(level = AccessLevel.PROTECTED)
public abstract class AbstractTaskProcessor implements TaskProcessor {
    @Inject
    RobotSelectProcessor           robotSelectProcessor;
    @Inject
    RobotMoveStubProcessor         robotMoveStubProcessor;
    @Inject
    RobotGiveUpProcessor           robotGiveUpProcessor;
    @Inject
    RobotMoveParkingSpaceProcessor robotMoveParkingSpaceProcessor;
    @Inject
    RobotPutDownProcessor          robotPutDownProcessor;
    @Inject
    RobotMoveBackProcessor         robotMoveBackProcessor;
    @Inject
    StubWakeUpProcessor            stubWakeUpProcessor;
    @Inject
    StubArmLeftProcessor           stubArmLeftProcessor;
    @Inject
    StubArmUpProcessor             stubArmUpProcessor;
    @Inject
    StubCableOutProcessor          stubCableOutProcessor;

    public void executeNextStep(TaskContext taskContext) {
        List<AbstractStepProcessor> steps = this.addSteps();
        Task                        task  = taskContext.getTask();

        if (task.getCurrentStepIndex() == null) {
            task.setStatus(TaskStatus.Doing);
            task.setCurrentStepIndex(0);
        } else {
            task.setCurrentStepIndex(task.getCurrentStepIndex() + 1);
        }

        if (hasNextNode(task)) {
            AbstractStepProcessor currentStep = steps.get(task.getCurrentStepIndex());
            task.setCurrentStep(currentStep);
            currentStep.execute(taskContext);
        } else {
            task.setStatus(TaskStatus.Finish);
            EventBus.publish(task.getTaskProcessor());
        }
    }

    private boolean hasNextNode(Task task) {
        return task.getCurrentStepIndex() < task.getTaskProcessor().addSteps().size();
    }

}
